#include "dialog.h"
#include "ui_dialog.h"

#include <QFileDialog>
#include <QDebug>
#include <QMessageBox>
#include <QProcess>

static const QString c_EMF(".emf");
static const QString c_JPG(".jpg");
static const QString c_HTM(".htm");

static const QString c_GlobHTM("*.htm");
static const QString c_GlobEMF("*.emf");

static const QString c_FixedSuffix("_fixed");
static const QString c_MainFileSuffix("_sfrm");
static const QString c_TocFileSuffix("_scnt");
static const QString c_DataFileSuffix("_dtl");

static const QString c_StylesheetFileName("default.css");

static const QString c_ConversionTool("MetaCon.exe");
static const QString c_AntiAliasOn("-A+");
static const QString c_From("-from");
static const QString c_To("-to");

static const QString c_ImagesDir("pixs");

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    qDebug() << "hello world";

    ui->setupUi(this);

    bool ConnectOK = false;
    ConnectOK = connect
    (
        ui->InputButton,
        SIGNAL(clicked()),
        this,
        SLOT(OnInputButtonClicked_())
    );
    Q_ASSERT(ConnectOK);

    ConnectOK = connect
    (
        ui->GenerateButton,
        SIGNAL(clicked()),
        this,
        SLOT(OnGenerateButtonClicked_())
    );
    Q_ASSERT(ConnectOK);
    Q_UNUSED(ConnectOK);
}

Dialog::~Dialog()
{
    delete ui;
}

void Dialog::OnInputButtonClicked_()
{
    QString InputDirPath = QFileDialog::getExistingDirectory(
        0,
        "Please select input directory");
    ui->InputLabel->setText(InputDirPath);
    ui->GenerateButton->setEnabled(!InputDirPath.isEmpty());
    m_InputDir.setPath(InputDirPath);
}

void Dialog::OnGenerateButtonClicked_()
{
    if (FindMainHtmlFile_())
    {
        if (CopyFiles_())
        {
            if (FixHtmlFiles_())
            {
                ConvertEmf2Jpg();
            }
        }
    }
}

bool Dialog::FindMainHtmlFile_()
{
    QStringList Filter("*" + c_HTM);
    QStringList HTMLFiles = m_InputDir.entryList(Filter);
    Q_FOREACH(QString File, HTMLFiles)
    {
        if(!File.contains('_'))
        {
            m_MainHtmlFileName = File.left(File.indexOf('.'));
            break;
        }
    }

    bool Success = true;
    if (m_MainHtmlFileName.isEmpty())
    {
        QMessageBox::critical(
            0,
            "Error!",
            "Main HTML file not found!");
        Success = false;
    }
    return Success;
}

bool Dialog::CopyFiles_()
{
    QString InputDirPath(m_InputDir.absolutePath());
    QString OutputDirPath(m_InputDir.absolutePath() + c_FixedSuffix);

    // Create a new directory
    if (!m_InputDir.mkpath(OutputDirPath))
    {
        QMessageBox::critical(
            0,
            "Error!",
            "Could not create directory:\n" + OutputDirPath);
        return false;
    }

    m_OutputDir.setPath(OutputDirPath);

    // Copy stylesheet file
    QString In = InputDirPath + '/' + c_StylesheetFileName;
    QString Out = OutputDirPath + '/' + c_StylesheetFileName;
    if (!CopyFile_(In, Out))
    {
        return false;
    }

    // Copy the Main_sfrm.htm file
    In = InputDirPath + '/' + m_MainHtmlFileName + c_MainFileSuffix + c_HTM;
    Out = OutputDirPath + '/' + m_MainHtmlFileName + c_HTM;
    if (!CopyFile_(In, Out))
    {
        return false;
    }

    // Copy the Main_scnt.htm file
    In = InputDirPath + '/' + m_MainHtmlFileName + c_TocFileSuffix + c_HTM;
    Out = OutputDirPath + '/' + m_MainHtmlFileName + c_TocFileSuffix + c_HTM;
    if (!CopyFile_(In, Out))
    {
        return false;
    }

    QStringList Filter(c_GlobHTM);
    QStringList HTMLFiles = m_InputDir.entryList(Filter);
    Q_FOREACH(QString File, HTMLFiles)
    {
        if (File.contains(c_DataFileSuffix))
        {
            In = InputDirPath + '/' + File;
            Out = OutputDirPath + '/' + File;
            if (!CopyFile_(In, Out))
            {
                return false;
            }
        }
    }

    return true;
}

bool Dialog::FixHtmlFiles_()
{
    QStringList Filter(c_GlobHTM);
    QFileInfoList HTMLFiles = m_OutputDir.entryInfoList(Filter);
    Q_FOREACH(QFileInfo FileInfo, HTMLFiles)
    {
        if(FileInfo.fileName().contains(c_DataFileSuffix))
        {
            QFile File(FileInfo.absoluteFilePath());
            if (File.open(QIODevice::ReadOnly))
            {
                QByteArray Contents = File.readAll();
                QByteArray Result = Contents.replace(".emf", ".jpg");
                File.close();

                if (File.open(QIODevice::WriteOnly | QIODevice::Truncate))
                {
                    if (File.write(Result) == -1)
                    {
                        QMessageBox::critical(
                            0,
                            "Error!",
                            "Failed to write entire file:\n" + File.fileName());
                        return false;
                    }
                }
                else
                {
                    QMessageBox::critical(
                        0,
                        "Error!",
                        "Failed to open file for writing:\n" + File.fileName());
                    return false;
                }
            }
            else
            {
                QMessageBox::critical(
                    0,
                    "Error!",
                    "Failed to open file for reading:\n" + File.fileName());
                return false;
            }
        }
    }

    return true;
}

void Dialog::ConvertEmf2Jpg()
{
    // Create a new directory
    QString OutputImagesDir = m_OutputDir.absolutePath() + "/" + c_ImagesDir;
    if (!m_OutputDir.mkpath(OutputImagesDir))
    {
        QMessageBox::critical(
            0,
            "Error!",
            "Could not create directory:\n" + OutputImagesDir);
        return;
    }

    QStringList Filter(c_GlobEMF);
    QDir ImagesDir(m_InputDir.absolutePath() + "/" + c_ImagesDir);
    QStringList EMFFiles = ImagesDir.entryList(Filter);
    QStringList Arguments;
    Q_FOREACH(QString FileName, EMFFiles)
    {
        Arguments.clear();
        Arguments.push_back(c_AntiAliasOn);
        Arguments.push_back(c_From);
        Arguments.push_back(m_InputDir.absolutePath() + "/" + c_ImagesDir + "/" + FileName);
        Arguments.push_back(c_To);
        Arguments.push_back(m_OutputDir.absolutePath() + "/" + c_ImagesDir + "/" + FileName.left(FileName.indexOf('.')) + c_JPG);

        int Return = QProcess::execute(c_ConversionTool, Arguments);

        if (-2 == Return)
        {
            QMessageBox::critical(
                0,
                "Error!",
                "Process cannot be started:\n" + c_ConversionTool);
            return;
        }

        if (-1 == Return)
        {
            QMessageBox::critical(
                0,
                "Error!",
                "Process crashed:\n" + c_ConversionTool);
            return;
        }
    }

    QMessageBox::information(
        0,
        "Success!",
        "Documentation fixed!");
}

bool Dialog::CopyFile_(const QString &rIn, const QString &rOut)
{
    QFile::remove(rOut);
    if (!QFile::copy(rIn, rOut))
    {
        QMessageBox::critical(
            0,
            "Error!",
            "Could not copy file from:\n" + rIn + "\nto:\n" + rOut);
        return false;
    }

    return true;
}
